package project2;

/*********************************************************************
* Precompute the T_u,v[i][j] tables used for the forward dynamic programming
* T_u,v[i][j] = TR_uv[n_u-i][n_v-j] with 0<=i<n_u and 0<=j<n_v
* TR_u,v can be used for the approximation step as well:
* TR_u,v[n_u][n_v] = the cost of an optimal alignment of s_u and s_v
* in my case I assume that all sequences have the same length
*********************************************************************/

public class precomputation {

    int[][][][] TR;
    String[] seq;
    int[][] score_matrix;
    int gap_cost, k, n;


    /*********************************************************************
     * constructor
     *********************************************************************/

    precomputation(int[][] score, int gap, String[] s, int k1, int n1) {
        //I have to copy each sequence in the reversed order
        score_matrix = score;
        gap_cost = gap;
        k = k1;
        seq = new String[k];
        for(int i=0; i<k; i++) {
            seq[i] = new String("");
            for(int j=s[i].length()-1; j>=0; j--)
                seq[i] = seq[i].concat(Character.toString(s[i].charAt(j)));
        }
        n = n1;
        TR = new int[k][k][n+1][n+1];
        TR();
    }


    /*********************************************************************
    * used to compute
    * score_matrix[value(s1.charAt(i-1))][value(s2.charAt(j-1))]
    *********************************************************************/

     int value(char c){
        if(c=='a') return 0;
        if(c=='c') return 1;
        if(c=='g') return 2;
        if(c=='t') return 3;
        return -1;
    }


    /*********************************************************************
    * global(int u, int v) computes the TR_u,v table
    *********************************************************************/

    void global(int u, int v) {
        for(int i=0; i<=n; i++) {
            for(int j=0; j<=n; j++) {
                int v1, v2, v3, v4;
                v1 = v2 = v3 = v4 = 50000;
                if((i>0)&&(j>0))
                    v1 = TR[u][v][i-1][j-1] + score_matrix[value(seq[u].charAt(i-1))][value(seq[v].charAt(j-1))];
                if((i>0)&&(j>=0))
                    v2 = TR[u][v][i-1][j] + gap_cost;
                if((i>=0)&&(j>0))
                    v3 = TR[u][v][i][j-1] + gap_cost;
                if((i==0)&&(j==0))
                    v4 = 0;
                TR[u][v][i][j] = java.lang.Math.min(java.lang.Math.min(v1, v2),java.lang.Math.min(v3, v4));
            }
        }
    }


    /*********************************************************************
    * compute the entire TR table
    *********************************************************************/

    void TR() {
        for(int i=0; i<k; i++) {
            for(int j=0; j<k; j++)
                if(i!=j)
                    global(i,j);
        }
    }


    /*********************************************************************
    * return the cost of an optimal alignment for seq[u] and seq[v]
    *********************************************************************/

    public int get_score(int u, int v) {
        return TR[u][v][n][n];
    }


    /*********************************************************************
    * return T_u,v[i][j]
    *********************************************************************/

    public int get_score(int u, int v, int i, int j) {
        return TR[u][v][n-i][n-j];
    }
    
}
